// ----------------------------------
// RSDK Project: Sonic 1
// Script Description: Act Finish Object
// Script Author: Christian Whitehead/Simon Thomley
// Unpacked by Rubberduckycooly's script unpacker
// ----------------------------------

// Looks like this is one of the objects that was programmed during the "S1 proto" phase, since it only uses values0-7 and doesn't use v4 syntax much at all

// ========================
// Aliases
// ========================

private alias object.xpos   : object.decorPos // "decor" is the blue circle btw
private alias object.ypos   : object.actPos
private alias object.value0 : object.timer
private alias object.value1 : object.playerNamePos
private alias object.value2 : object.passedPos
private alias object.value3 : object.totalPos
private alias object.value4 : object.timePos
private alias object.value5 : object.timeBonus
private alias object.value6 : object.ringBonus
private alias object.scale  : object.ringPos

// States
private alias -1 : ACTFINISH_NORESULTS
private alias  0 : ACTFINISH_INIT
private alias  1 : ACTFINISH_ENTERACTFINISH
private alias  2 : ACTFINISH_ENTERPASSEDTEXT
private alias  3 : ACTFINISH_ENTERACTID
private alias  4 : ACTFINISH_ENTERBONUSES
private alias  5 : ACTFINISH_ACTFINISHJINGLE
private alias  6 : ACTFINISH_TALLYSCORE
private alias  7 : ACTFINISH_SHOWRESULTS
private alias  8 : ACTFINISH_LOADNEXTSTAGE
private alias  9 : ACTFINISH_EXITUISPRITES
private alias 10 : ACTFINISH_EXITTEXT
private alias 11 : ACTFINISH_EXITSCORES
private alias 12 : ACTFINISH_WAITFORCALLBACK
private alias 13 : ACTFINISH_RETRY
private alias 14 : ACTFINISH_SETSCREENFADE

// Game Modes Aliases
private alias 1 : MODE_SAVEGAME
private alias 2 : MODE_TIMEATTACK

// Super States
private alias 1 : SUPERSTATE_SUPER
private alias 2 : SUPERSTATE_UNTRANSFORM

// Player Aliases
private alias object.type        : player.type
private alias object.interaction : player.interaction
private alias object.controlMode : player.controlMode
private alias object.right       : player.right

private alias object.value0 : player.rings

// Sign Post Aliases
private alias 5 : SIGNPOST_BLANK


// ========================
// Events
// ========================

event ObjectUpdate
	switch object.state
	case ACTFINISH_INIT
		object.drawOrder = 6
		object.priority = PRIORITY_ACTIVE

		object.decorPos = screen.xcenter
		object.decorPos += 128
		object.actPos = screen.xcenter
		
		object.playerNamePos = screen.xcenter
		FlipSign(object.playerNamePos)
		object.playerNamePos -= 160
		
		object.passedPos = screen.xcenter
		FlipSign(object.passedPos)
		object.passedPos -= 160
		
		object.totalPos = screen.xcenter
		object.totalPos += 128
		
		object.timePos = object.totalPos
		object.timePos += 32
		
		object.ringPos = object.timePos
		object.ringPos += 32

		if Player_superState == SUPERSTATE_SUPER
			Player_superState = SUPERSTATE_UNTRANSFORM
		end if

		switch stage.minutes
		case 0
			if stage.seconds < 30
				object.timeBonus = 50000
			else
				if stage.seconds < 45
					object.timeBonus = 10000
				else
					object.timeBonus = 5000
				end if
			end if
			break

		case 1
			if stage.seconds < 30
				object.timeBonus = 4000
			else
				object.timeBonus = 3000
			end if
			break

		case 2
			object.timeBonus = 2000
			break

		case 3
			object.timeBonus = 1000
			break

		case 4
			object.timeBonus = 500
			break

		case 5
			object.timeBonus = 100
			break

		case 9
			// If the player finished the stage at the last possible moment, then reward a whole lotta points!
			// Fun note - this wasn't in the initial versions of S1, back then the time bonus stopped at 5 minutes and that was it
			if stage.debugMode == false
				if options.gameMode < MODE_TIMEATTACK
					if stage.seconds == 59
						object.timeBonus = 100000
					end if
				end if
			end if
			break

		end switch

		object.ringBonus = player[0].rings
		object.ringBonus *= 100
		
#platform: USE_ORIGINS
		if game.playMode == BOOT_PLAYMODE_MISSION
			object.state = ACTFINISH_NORESULTS
		else
			if game.playMode == BOOT_PLAYMODE_BOSSRUSH
				object.state = ACTFINISH_NORESULTS
			else
				object.state++
			end if
		end if
		
		CallNativeFunction4(NotifyCallback, NOTIFY_STATS_ENEMY, StageStatsUsabilityParam1, StageStatsUsabilityParam2, StageStatsUsabilityParam3)
		CallNativeFunction2(NotifyCallback, NOTIFY_STATS_RING, player[0].rings)
		CallNativeFunction2(NotifyCallback, NOTIFY_ACT_FINISH, 0)
		
		StageStatsUsabilityParam1 = 0
		StageStatsUsabilityParam2 = 0
		StageStatsUsabilityParam3 = 0
		StageStatsUsabilityParam4 = 0
		StageStatsUsabilityParam5 = 0
		StatsUsabilityParam1 = 0
		StatsUsabilityParam2 = 0
		StatsUsabilityParam3 = 0
		StatsUsabilityParam4 = 0
		StatsUsabilityParam5 = 0
#endplatform

#platform: USE_STANDALONE
		object.state++
#endplatform
		break

	case ACTFINISH_ENTERACTFINISH
		if object.decorPos > 0
			object.decorPos -= 16
			if object.decorPos < 0
				object.decorPos = 0
			end if
		end if

		if object.playerNamePos < 0
			object.playerNamePos += 16
			if object.playerNamePos > 0
				object.playerNamePos = 0
			end if
		else
			object.state++
		end if
		break

	case ACTFINISH_ENTERPASSEDTEXT
		if object.passedPos < 0
			object.passedPos += 16
			if object.passedPos > 0
				object.passedPos = 0
			end if
		else
			object.state++
		end if
		break
		
	case ACTFINISH_ENTERACTID
		if object.actPos > 0
			object.actPos -= 16
			if object.actPos < 0
				object.actPos = 0
			end if
		else
			object.state++
		end if
		break

	case ACTFINISH_ENTERBONUSES
		if object.totalPos > 0
			object.totalPos -= 16
			if object.totalPos < 0
				object.totalPos = 0
			end if
		end if

		if object.timePos > 0
			object.timePos -= 16
			if object.timePos < 0
				object.timePos = 0
			end if
		end if

		if object.ringPos > 0
			object.ringPos -= 16
			if object.ringPos < 0
				object.ringPos = 0
			end if
		else
			object.state++
		end if
		break

	case ACTFINISH_ACTFINISHJINGLE
		object.timer++
		if object.timer > 299
			object.timer = 0
			object.state++
		end if
		break

	case ACTFINISH_TALLYSCORE
		if object.ringBonus > 0
			object.ringBonus -= 100
			player.score += 100
		end if

		if object.timeBonus > 0
			object.timeBonus -= 100
			player.score += 100
		end if

		CheckGreater(object.ringBonus, 0)
		temp0 = checkResult
		CheckGreater(object.timeBonus, 0)
		temp0 |= checkResult
		if temp0 == true
			object.timer++
			if object.timer == 2
				PlaySfx(SfxName[Score Add], false)
				object.timer = 0
			end if
		else
			object.state++
			object.timer = 0
			PlaySfx(SfxName[Score Total], false)
		end if
		break

	case ACTFINISH_SHOWRESULTS
		object.timer++
		if object.timer == 160
			object.timer = 0

			if options.gameMode != MODE_TIMEATTACK
				CheckCurrentStageFolder("Zone06")
				temp0 = checkResult
				CheckEqual(stage.actNum, 2)
				temp0 &= checkResult
#platform: USE_ORIGINS
				CheckEqual(game.oneStageFlag, false)
				temp0 &= checkResult
#endplatform
				if temp0 == true
					// In SBZ Act 2, exit the HUD rather than fading out to the next level
					object.state = ACTFINISH_EXITUISPRITES
				else
#platform: USE_ORIGINS
					if game.oneStageFlag != false
						game.callbackResult = -1
						CallNativeFunction4(NotifyCallback, NOTIFY_STAGE_RETRY, true, stage.listPos, 0)
						object.state = ACTFINISH_WAITFORCALLBACK
					else
						object.state++
					end if
#endplatform
#platform: USE_STANDALONE
					object.state++
#endplatform
					if player[0].type == TypeName[Blank Object]
						PlaySfx(SfxName[Warp], false)
					end if
				end if
			else
#platform: USE_ORIGINS
				if game.oneStageFlag != false
					game.callbackResult = -1
					CallNativeFunction4(NotifyCallback, NOTIFY_STAGE_RETRY, true, stage.listPos, 0)
					object.state = ACTFINISH_WAITFORCALLBACK
				else
					object.state++
				end if
#endplatform
#platform: USE_STANDALONE
				object.state++
#endplatform
				if player[0].type == TypeName[Blank Object]
					PlaySfx(SfxName[Warp], false)
				end if
			end if
		end if
		break

	case ACTFINISH_LOADNEXTSTAGE
		if player[0].type == TypeName[Blank Object]
			// If the player object is blank, then they entered a Special Ring
			// So, off to the Special Stage!
			object.timer += 8
			SetScreenFade(208, 255, 224, object.timer)
			if object.timer == 0x400
				fadeColor = 208
				fadeColor <<= 16
				temp0 = 255
				temp0 <<= 8
				fadeColor += temp0
				fadeColor += 224
				object.direction = FACING_RIGHT // huh? does this even matter?
				object.timer = 0
				lampPostID = 0
				stage.listPos++

				if options.gameMode == MODE_SAVEGAME
					arrayPos1 = options.saveSlot
					arrayPos1 <<= 3
					if stage.player2Enabled == true
#platform: USE_STANDALONE
						saveRAM[arrayPos1] = 3
#endplatform

#platform: USE_ORIGINS
						switch stage.playerListPos
						case PLAYER_SONIC_A
							saveRAM[arrayPos1] = PLAYER_SONIC_TAILS_A
							break
						case PLAYER_AMY_A
							saveRAM[arrayPos1] = PLAYER_AMY_TAILS_A
							break
						end switch
#endplatform
					else
						saveRAM[arrayPos1] = stage.playerListPos
					end if
					arrayPos1++
					saveRAM[arrayPos1] = player.lives
					arrayPos1++
					saveRAM[arrayPos1] = player.score
					arrayPos1++
					saveRAM[arrayPos1] = player.scoreBonus
					arrayPos1++
					temp0 = stage.listPos
					temp0++
					if temp0 > saveRAM[arrayPos1]
						saveRAM[arrayPos1] = temp0
						saveRAM[arrayPos1] += 0x80
					end if
					arrayPos1++
					saveRAM[arrayPos1] = specialStage.emeralds
					arrayPos1++
					saveRAM[arrayPos1] = specialStage.listPos
					WriteSaveRAM()
				end if

				specialStage.nextZone = stage.listPos
				stage.listPos = specialStage.listPos
				stage.activeList = SPECIAL_STAGE
				
				temp0 = engine.trialMode
				if stage.listPos >= stage.listSize
					temp0 = true
				end if

				if temp0 == false
					LoadStage()
				else
					// Invalid Stage, Go back to the title screen
					stage.activeList = PRESENTATION_STAGE
					stage.listPos = 0
					LoadStage()
				end if
			end if
		else
			object.timer += 4
			SetScreenFade(0, 0, 0, object.timer)
			if object.timer == 384
				fadeColor = 0
				object.timer = 0
				lampPostID = 0
				object.direction = FACING_RIGHT // i don't think this does anything...
				stage.listPos++

				if options.gameMode == MODE_SAVEGAME
					arrayPos1 = options.saveSlot
					arrayPos1 <<= 3
					if stage.player2Enabled == true
#platform: USE_STANDALONE
						saveRAM[arrayPos1] = PLAYER_SONIC_TAILS_A
#endplatform

#platform: USE_ORIGINS
						switch stage.playerListPos
						case PLAYER_SONIC_A
							saveRAM[arrayPos1] = PLAYER_SONIC_TAILS_A
							break
						case PLAYER_AMY_A
							saveRAM[arrayPos1] = PLAYER_AMY_TAILS_A
							break
						end switch
#endplatform
					else
						saveRAM[arrayPos1] = stage.playerListPos
					end if
					arrayPos1++
					saveRAM[arrayPos1] = player.lives
					arrayPos1++
					saveRAM[arrayPos1] = player.score
					arrayPos1++
					saveRAM[arrayPos1] = player.scoreBonus
					arrayPos1++
					temp0 = stage.listPos
					temp0++
					if temp0 > saveRAM[arrayPos1]
						saveRAM[arrayPos1] = temp0
					end if
					arrayPos1++
					saveRAM[arrayPos1] = specialStage.emeralds
					arrayPos1++
					saveRAM[arrayPos1] = specialStage.listPos
					WriteSaveRAM()
				end if

				if options.gameMode == MODE_TIMEATTACK
					timeAttack.result = stage.seconds
					timeAttack.result *= 100
					temp0 = stage.minutes
					temp0 *= 0x1770
					timeAttack.result += temp0
					timeAttack.result += stage.milliSeconds
					stage.listPos--
					CallNativeFunction2(SetLeaderboard, stage.listPos, timeAttack.result)
					engine.state = 8
				else
					temp0 = engine.trialMode
					if stage.listPos >= stage.listSize
						temp0 = true
					end if

					if temp0 == false
						LoadStage()
					else
						// Invalid Stage, Go back to the title screen
						stage.activeList = PRESENTATION_STAGE
						stage.listPos = 0
						LoadStage()
					end if
				end if
			end if
		end if
		break

	case ACTFINISH_EXITUISPRITES
		object.decorPos += 32
		object.actPos += 32
		object.playerNamePos -= 32
		object.timer++
		if object.timer == 8
			object.timer = 0
			object.state++
		end if
		break

	case ACTFINISH_EXITTEXT
		object.decorPos += 32
		object.actPos += 32
		object.playerNamePos -= 32
		object.passedPos -= 32
		object.timer++
		if object.timer == 8
			object.timer = 0
			object.state++
		end if
		break

	case ACTFINISH_EXITSCORES
		object.decorPos += 32
		object.actPos += 32
		object.playerNamePos -= 32
		object.passedPos -= 32
		object.totalPos += 32
		if object.totalPos > 96
			object.timePos += 32
			if object.timePos > 96
				object.ringPos += 32
			end if
		end if

		object.timer++
		if object.timer == 35
			object.timer = 0
			temp0 = tileLayer[0].xsize
			temp0 <<= 7
			stage.newXBoundary2 = temp0
			foreach (TypeName[Sign Post], arrayPos0, ACTIVE_ENTITIES)
				object[arrayPos0].state = SIGNPOST_BLANK
			next

			currentPlayer = 0
			while currentPlayer < playerCount
				player[currentPlayer].interaction 	= true
#platform: USE_STANDALONE
				player[currentPlayer].controlMode = CONTROLMODE_P1
#endplatform
#platform: USE_ORIGINS
				player[currentPlayer].controlMode = currentPlayer
#endplatform
				player[currentPlayer].right 		= true
				currentPlayer++
			loop

			ResetObjectEntity(object.entityPos, TypeName[Blank Object], 0, 0, 0)
			SetMusicTrack("Final.ogg", 0, 84680)
			PlayMusic(0)
		end if
		break
		
#platform: USE_ORIGINS
	case ACTFINISH_WAITFORCALLBACK
		if game.callbackResult >= 0
			object.state = ACTFINISH_LOADNEXTSTAGE // I think this is supposed to set it to the next state instead of this one...
		end if
		break
		
	case ACTFINISH_RETRY
		if game.callbackResult == 0
			engine.state = 8
		else
			LoadStage()
		end if
		
		object.state++
		if player[0].type == TypeName[Blank Object]
			SetScreenFade(208, 255, 224, 255)
		else
			SetScreenFade(0, 0, 0, 255)
		end if
		break
		
	case ACTFINISH_SETSCREENFADE
		if player[0].type == TypeName[Blank Object]
			SetScreenFade(208, 255, 224, 255)
		else
			SetScreenFade(0, 0, 0, 255)
		end if
		break
#endplatform
	end switch
end event


event ObjectDraw
	SetActivePalette(0, 0, screen.ysize)

	temp0 = screen.xcenter
	temp0 += 16
	temp0 += object.decorPos
	DrawSpriteScreenXY(3, temp0, 56) // Blue Circle

	temp0 = screen.xcenter
	temp0 += 3
	temp0 += object.playerNamePos
#platform: USE_STANDALONE
	DrawSpriteScreenXY(stage.playerListPos, temp0, 60) // Player name
#endplatform

#platform: USE_ORIGINS
	if stage.playerListPos != PLAYER_AMY_A
		DrawSpriteScreenXY(stage.playerListPos, temp0, 60)
	else
		DrawSpriteScreenXY(23, temp0, 60)
	end if
#endplatform

	DrawSpriteScreenXY(4, temp0, 60) // "Has"

	temp0 = screen.xcenter
	temp0 -= 48
	temp0 += object.passedPos
	DrawSpriteScreenXY(5, temp0, 80) // "Passed"

	temp0 = screen.xcenter
	temp0 += 24
	temp0 += object.actPos
	temp1 = stage.actNum
	temp1 += 5
	if temp1 < 6
		// Minimum of Act 1 to be displayed
		temp1 = 6
	end if
	if temp1 > 8
		// Maximum of Act 3 to be displayed
		temp1 = 8
	end if
	DrawSpriteScreenXY(temp1, temp0, 82) //  Act number

	temp0 = screen.xcenter
	temp0 -= 79
	temp0 += object.totalPos
	DrawSpriteScreenXY(9, temp0, 117) // "Score" text

	temp0 += 151
	DrawNumbers(13, temp0, 117, player.score, 6, 8, false)

	temp0 = screen.xcenter
	temp0 -= 79
	temp0 += object.timePos
	DrawSpriteScreenXY(10, temp0, 133) // "Time" text
	DrawSpriteScreenXY(12, temp0, 133) // "Bonus" text

	temp0 += 151
	DrawNumbers(13, temp0, 133, object.timeBonus, 6, 8, false)

	temp0 = screen.xcenter
	temp0 -= 79
	temp0 += object.ringPos
	DrawSpriteScreenXY(11, temp0, 149) // "Rings" text
	DrawSpriteScreenXY(12, temp0, 149) // "Bonus" text

	temp0 += 151
	DrawNumbers(13, temp0, 149, object.ringBonus, 5, 8, false)
end event


event ObjectStartup
	LoadSpriteSheet("Global/Display.gif")

	// Results frames
	SpriteFrame(-70, 0, 70, 16, 1, 222) 		// #0  - "Sonic"

	SpriteFrame(-89, 0, 178, 16, 1, 256) 		// #1  - "Rainbow Dash"

	SpriteFrame(-93, 0, 113, 16, 142, 222) 		// #2  - "Knuckles"

	switch stage.playerListPos
	case PLAYER_KNUCKLES_A
		SpriteFrame(20, 0, 56, 56, 41, 1) 		// #3  - Title card blue circle
		SpriteFrame(37, 0, 47, 16, 1, 205) 		// #4  - "Has"
		SpriteFrame(20, 0, 95, 16, 49, 205) 	// #5  - "Passed"
		SpriteFrame(20, 0, 39, 24, 98, 1) 		// #6  - Act 1 sign
		SpriteFrame(20, 0, 43, 24, 138, 1) 		// #7  - Act 2 sign
		SpriteFrame(20, 0, 43, 24, 182, 1) 		// #8  - Act 3 sign
		break

	case PLAYER_TAILS_A
		SpriteFrame(34, 0, 56, 56, 41, 1) 		// #3  - Title card blue circle
		SpriteFrame(0, 0, 1, 1, 1, 1) 			// #4  - null
		SpriteFrame(-28, 0, 157, 16, 1, 273) 		// #5  - "Has Passed"
		SpriteFrame(34, 0, 39, 24, 98, 1) 		// #6  - Act 1 sign
		SpriteFrame(34, 0, 43, 24, 138, 1) 		// #7  - Act 2 sign
		SpriteFrame(34, 0, 43, 24, 182, 1) 		// #8  - Act 3 sign
		break

	case PLAYER_SONIC_A
	case PLAYER_SONIC_TAILS_A
		SpriteFrame(0, 0, 56, 56, 41, 1) 		// #3  - Title card blue circle
		SpriteFrame(17, 0, 47, 16, 1, 205) 		// #4  - "Has"
		SpriteFrame(0, 0, 95, 16, 49, 205) 		// #5  - "Passed"
		SpriteFrame(0, 0, 39, 24, 98, 1) 		// #6  - Act 1 sign
		SpriteFrame(0, 0, 43, 24, 138, 1) 		// #7  - Act 2 sign
		SpriteFrame(0, 0, 43, 24, 182, 1) 		// #8  - Act 3 sign
		break

	end switch

	SpriteFrame(0, -2, 44, 16, 161, 26)  		// #9  - "Score"
	SpriteFrame(0, 0, 31, 11, 1, 17)  			// #10 - "Time" (cropped from normal HUD graphic)
	SpriteFrame(0, 0, 31, 11, 1, 33)  			// #11 - "Rings" (also cropped from normal HUD graphic)
	SpriteFrame(40, -2, 45, 16, 98, 43)  		// #12 - "Bonus"
	SpriteFrame(0, 0, 8, 11, 1, 50)  			// #13 - Number 0
	SpriteFrame(0, 0, 8, 11, 10, 50)  			// #14 - Number 1
	SpriteFrame(0, 0, 8, 11, 19, 50)  			// #15 - Number 2
	SpriteFrame(0, 0, 8, 11, 28, 50)  			// #16 - Number 3
	SpriteFrame(0, 0, 8, 11, 1, 62)  			// #17 - Number 4
	SpriteFrame(0, 0, 8, 11, 10, 62)  			// #18 - Number 5
	SpriteFrame(0, 0, 8, 11, 19, 62)  			// #19 - Number 6
	SpriteFrame(0, 0, 8, 11, 28, 62)  			// #20 - Number 7
	SpriteFrame(0, 0, 8, 11, 1, 74)  			// #21 - Number 8
	SpriteFrame(0, 0, 8, 11, 10, 74)  			// #22 - Number 9
	
#platform: USE_ORIGINS
	SpriteFrame(-43, 0, 47, 16, 182, 166)		// #23 - "Amy"
#endplatform
end event


// ========================
// Editor Events
// ========================

event RSDKDraw
	DrawSprite(0)
end event


event RSDKLoad
	LoadSpriteSheet("Global/Display.gif")
	SpriteFrame(-16, -16, 32, 32, 1, 143)
	
	SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")
end event

